package com.api.sw.duban.util;


import org.apache.commons.lang.StringUtils;
import org.apache.poi.util.Units;
import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
import sun.misc.BASE64Decoder;

import java.io.*;
import java.math.BigInteger;
import java.text.SimpleDateFormat;
import java.util.*;
/*
    不符合 先行在列
 */
public class WordExport {
    private final static LogTool log = new LogTool("/log/duban/",false);
    public final static int DOCW=26002;
    public final static int DOCH=16840;
    private XWPFDocument document;
    private FileOutputStream out;
    private File file;
    private String path;

    public WordExport(XWPFDocument document) {
        this.document = document;
    }

    public XWPFDocument getDocument() {
        return document;
    }

    public WordExport(String path) {
        this.path = path;
    }

    public File getFile() {
        return file;
    }

    public void setFile(File file) {
        this.file = file;
    }
    //设置表格的大小
    public WordExport(int W ,int H){
        this.document= new XWPFDocument();
        CTDocument1 document1 = document.getDocument();
        CTBody body = document1.getBody();
        if(!body.isSetSectPr()){
            body.addNewSectPr();
        }
        CTSectPr section = body.getSectPr();

        if(!section.isSetPgSz()){
            section.addNewPgSz();
        }
        CTPageSz pageSize = section.getPgSz();
        pageSize.setW(BigInteger.valueOf(W));
        pageSize.setH(BigInteger.valueOf(H));
        pageSize.setOrient(STPageOrientation.LANDSCAPE);
    }
    /**
     * @param title    pdf的标题
     * @param headList 表格头部的list数据
     * @param dataList 表格下方的内容数据   按顺序填入集合中即可
     */
    public void makeWord(List<String> title,List<List<String>> headList, List<String> dataList, String note,int[] colWidths,String path) {


        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        String format = simpleDateFormat.format(new Date());

            for (int i = 0; i < title.size(); i++) {
                if (i == 0) {
                    if (StringUtils.isNotBlank(title.get(i))) {
                        //添加标题
                        XWPFParagraph titleParagraph = document.createParagraph();
                        //设置段落居中
                        titleParagraph.setAlignment(ParagraphAlignment.CENTER);
                        XWPFRun titleParagraphRun = titleParagraph.createRun();
                        titleParagraphRun.setText(title.get(i));
                        titleParagraphRun.setColor("000000");
                        titleParagraphRun.setFontSize(20);
                    }
                    if (StringUtils.isNotBlank(note)) {
                        //添加标题
                        XWPFParagraph titleParagraph = document.createParagraph();
                        XWPFRun titleParagraphRun = titleParagraph.createRun();
                        titleParagraphRun.setText(note);
                        titleParagraphRun.setFontSize(10);
                    }
                } else {
                    //二级标题
                    //添加标题
                    XWPFParagraph titleParagraph = document.createParagraph();
                    //设置段落居中
                    XWPFRun titleParagraphRun = titleParagraph.createRun();
                    titleParagraphRun.setText(title.get(i));
                    titleParagraphRun.setColor("000000");
                    titleParagraphRun.setFontSize(15);
                }
            }
        if (headList != null) {
            try {
                makeData(headList, dataList,colWidths,path);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }
    /**
     * @param title    pdf的标题
     * @param headList 表格头部的list数据
     * @param dataList 表格下方的内容数据   按顺序填入集合中即可
     */
    public void makeWord(List<String> title,List<List<String>> headList, List<String> dataList, String note,int[] colWidths) {


        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        String format = simpleDateFormat.format(new Date());

        for (int i = 0; i < title.size(); i++) {
            if (i == 0) {
                if (StringUtils.isNotBlank(title.get(i))) {
                    //添加标题
                    XWPFParagraph titleParagraph = document.createParagraph();
                    //设置段落居中
                    titleParagraph.setAlignment(ParagraphAlignment.CENTER);
                    XWPFRun titleParagraphRun = titleParagraph.createRun();
                    titleParagraphRun.setText(title.get(i));
                    titleParagraphRun.setColor("000000");
                    titleParagraphRun.setFontSize(25);
                    titleParagraphRun.setBold(true);
                    titleParagraphRun.addBreak();//换行
                }
                if (StringUtils.isNotBlank(note)) {
                    //添加标题
                    XWPFParagraph titleParagraph = document.createParagraph();
                    XWPFRun titleParagraphRun = titleParagraph.createRun();
                    titleParagraphRun.setText(note);
                    titleParagraphRun.setFontSize(10);
                }
            } else {
                //二级标题
                //添加标题
                XWPFParagraph titleParagraph = document.createParagraph();
                //设置段落居中
                XWPFRun titleParagraphRun = titleParagraph.createRun();
                titleParagraphRun.setText(title.get(i));
                titleParagraphRun.setColor("000000");
                titleParagraphRun.setFontSize(15);
            }
        }
        //设置 制表日期
        XWPFParagraph zbParagraph = document.createParagraph();
        zbParagraph.setAlignment(ParagraphAlignment.RIGHT);
        XWPFRun zbParagraphRun = zbParagraph.createRun();
        zbParagraphRun.setText("制表日期: "+BaseUtil.getCreateDate());
        zbParagraphRun.setColor("000000");


        if (headList != null) {
            try {
                makeData(headList, dataList,colWidths);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }

    /**
     * 新的计划导出合并 第一行得 列
     * @param title    pdf的标题
     * @param headList 表格头部的list数据
     * @param dataList 表格下方的内容数据   按顺序填入集合中即可
     */
    public void makeWordjH(List<String> title,List<List<String>> headList, List<String> dataList, String note,int[] colWidths,String jhlx) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        String format = simpleDateFormat.format(new Date());

        for (int i = 0; i < title.size(); i++) {
            if (i == 0) {
                if (StringUtils.isNotBlank(title.get(i))) {
                    //添加标题
                    XWPFParagraph titleParagraph = document.createParagraph();
                    //设置段落居中
                    titleParagraph.setAlignment(ParagraphAlignment.CENTER);
                    XWPFRun titleParagraphRun = titleParagraph.createRun();
                    titleParagraphRun.setText(title.get(i));
                    titleParagraphRun.setColor("000000");
                    titleParagraphRun.setFontSize(25);
                    titleParagraphRun.setBold(true);
                    titleParagraphRun.addBreak();//换行
                }
                if (StringUtils.isNotBlank(note)) {
                    //添加标题
                    XWPFParagraph titleParagraph = document.createParagraph();
                    XWPFRun titleParagraphRun = titleParagraph.createRun();
                    titleParagraphRun.setText(note);
                    titleParagraphRun.setFontSize(10);
                }
            } else {
                //二级标题
                //添加标题
                XWPFParagraph titleParagraph = document.createParagraph();
                //设置段落居中
                XWPFRun titleParagraphRun = titleParagraph.createRun();
                titleParagraphRun.setText(title.get(i));
                titleParagraphRun.setColor("000000");
                titleParagraphRun.setFontSize(15);
            }
        }
        //设置 制表日期
        XWPFParagraph zbParagraph = document.createParagraph();
        zbParagraph.setAlignment(ParagraphAlignment.RIGHT);
        XWPFRun zbParagraphRun = zbParagraph.createRun();
        zbParagraphRun.setText("制表日期: "+BaseUtil.getCreateDate());
        zbParagraphRun.setColor("000000");


        if (headList != null) {
            try {
                makeDataJh(headList, dataList,colWidths,jhlx);
            } catch (Exception e) {
                log.writeLog("play exception--->"+e.getMessage());
                e.printStackTrace();
            }
        }

    }

    public WordExport(String filePath, String fileName) {

        fileName = fileName.replaceAll("/", "");
        fileName = fileName.replaceAll("\\\\", "");
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        String format = simpleDateFormat.format(new Date());
        filePath += format + File.separator;
        File file = new File(filePath + fileName);
        document = new XWPFDocument();    /*document对象可以只创建一次*/
        this.file = file;
    }


    /**
     * 合并单元格方法
     *
     * @param list     表格头部数据 list中相连下标位置内容如果相同自动合并 上下位置内容相同自动合并
     * @param dataList 表格内容数据   按顺序填入集合中即可
     * @return
     */
    public void makeData(List<List<String>> list, List<String> dataList,int[] colWidths,String path) throws Exception {
        int length = list.get(0).size();
        List<List<Map<String, String>>> aa = new ArrayList<>();

        for (int i = 0; i < list.size(); i++) {
            List<String> strings = list.get(i);
            int colNum = 1;
            List<Map<String, String>> bb = new ArrayList<>();
            for (int j = 0; j < strings.size(); j++) {
                if (j + 1 < strings.size()) {
                    if (strings.get(j).equals(strings.get(j + 1))&&false) {//不过滤行
                        colNum++;
                    } else {
                        Map<String, String> map = new HashMap<>();
                        map.put("value", strings.get(j));
                        map.put("colspan", colNum + "");

                        bb.add(map);

                        for (int a = 1; a < colNum; a++) {
                            bb.add(null);
                        }
                        colNum = 1;
                    }
                } else {
                    System.out.println("de"+colNum);
                    Map<String, String> map = new HashMap<>();
                    map.put("value", strings.get(j));
                    map.put("colspan", colNum + "");
                    bb.add(map);
                    for (int a = 1; a < colNum; a++) {
                        bb.add(null);
                    }
                    colNum = 1;
                }
            }
            aa.add(bb);
        }
        System.out.println(aa.toString());
        for (int i = 0; i < length; i++) {

            int rowSpan = 1;
            int begrow=0;

            for (int j = 0; j < aa.size(); j++) {

                if (aa.get(j).get(i) == null) {
                    continue;
                }

                if (j + 1 < aa.size()) {

                    if (checkValue(list,j,(j+(1)),i)&&aa.get(j + 1).get(i) != null && aa.get(j).get(i).get("value").equals(aa.get(j + 1).get(i).get("value"))
                            && aa.get(j).get(i).get("colspan").equals(aa.get(j + 1).get(i).get("colspan"))
                    ) {

                        rowSpan++;
                    } else {
                        //checkValue(list,0,0,i)&&
                            begrow=j;
                            aa.get(j - rowSpan + 1).get(i).put("rowSpan", rowSpan + "");

                            for (int a = 1; a < rowSpan; a++) {
                                aa.get(j - rowSpan + 1 + a).set(i, null);
                            }
                            rowSpan = 1;


                    }
                } else {
                    begrow=j;
                    aa.get(j - rowSpan + 1).get(i).put("rowSpan", rowSpan + "");

                    for (int a = 1; a < rowSpan; a++) {
                        aa.get(j - rowSpan + 1 + a).set(i, null);
                    }
                    rowSpan = 1;
                }
            }
        }


        List<List<Map<String, Boolean>>> mergeList = new ArrayList<>();
        for (int i = 0; i < aa.size(); i++) {
            List<Map<String, Boolean>> list1 = new ArrayList<>();
            for (int j = 0; j < aa.get(0).size(); j++) {

                Map<String, String> map1 = aa.get(i).get(j);

                if (map1 != null && map1.size() >= 3) {
                    int rowSpan = Integer.parseInt(map1.get("rowSpan"));
                    int colspan = Integer.parseInt(map1.get("colspan"));

                    if (colspan > 1) {

                        aa.get(i).get(j).put("isColStart", "true");

                        for (int a = 1; a < colspan; a++) {
                            Map<String, String> map = new HashMap<>();
                            map.put("isColContinue", "true");
                            aa.get(i).set(j + a, map);
                        }
                    }
                    if (rowSpan > 1) {

                        aa.get(i).get(j).put("isRowStart", "true");

                        if (colspan > 1) {
                            for (int a = 1; a < rowSpan; a++) {
                                Map<String, String> map = new HashMap<>();
                                map.put("isRowContinue", "true");
                                aa.get(i + a).set(j, map);

                                for (int b = 1; b < colspan; b++) {
                                    Map<String, String> map2 = new HashMap<>();
                                    map2.put("isColContinue", "true");
                                    map2.put("isRowContinue", "true");
                                    aa.get(i + a).set(j + b, map2);
                                }
                            }
                        } else {
                            for (int a = 1; a < rowSpan; a++) {
                                Map<String, String> map = new HashMap<>();
                                map.put("isRowContinue", "true");
                                aa.get(i + a).set(j, map);
                            }
                        }
                    }

                }
            }
            mergeList.add(list1);
        }

        //基本信息表格
        XWPFTable infoTable = document.createTable(dataList == null ? list.size() : list.size() + dataList.size() / list.get(0).size(), list.get(0).size());
        //设置指定宽度
        CTTbl ttbl = infoTable.getCTTbl();
        CTTblGrid tblGrid = ttbl.addNewTblGrid();
        for (int i : colWidths) {
            CTTblGridCol gridCol = tblGrid.addNewGridCol();
            gridCol.setW(new BigInteger(i+""));
        }
        //
        //CTTblWidth comTableWidth = infoTable.getCTTbl().addNewTblPr().addNewTblW();
        //comTableWidth.setType(STTblWidth.DXA);
        //comTableWidth.setW(BigInteger.valueOf(9072));



        for (int i = 0; i < list.size(); i++) {
            //表格第一行
            XWPFTableRow infoTableRowOne = infoTable.getRow(i);
            for (int j = 0; j < list.get(0).size(); j++) {

                Map<String, String> map = aa.get(i).get(j);

                if (map.get("isColStart") != null) {
                    //infoTableRowOne.getCell(j).getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.RESTART);//这是起点
                }
                if (map.get("isRowStart") != null) {
                    infoTableRowOne.getCell(j).getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.RESTART);//这是起点
                }
                if (map.get("isColContinue") != null) {
                    //infoTableRowOne.getCell(j).getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.CONTINUE);//这是起点
                }
                if (map.get("isRowContinue") != null) {
                    infoTableRowOne.getCell(j).getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.CONTINUE);//这是起点
                }
                if (map.get("value") != null) {
                    infoTableRowOne.getCell(j).setText(map.get("value"));
                }
                XWPFParagraph XWPFParagraph1=(XWPFParagraph)infoTableRowOne.getCell(j).getParagraphs().get(0);
                XWPFParagraph1.setAlignment(ParagraphAlignment.CENTER);  //设置水平居中

                infoTableRowOne.getCell(j).setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);  //设置垂直居中
            }
        }
        int row = list.size() - 1;
        int col = 0;
        for (int i = 0; i < dataList.size(); i++) {
            if (i % list.get(0).size() == 0) {
                row++;
                col = 0;
            }
            //infoTable.getRow(row).getCell(col).setText(dataList.get(i));

            XWPFParagraph celXWPFParagraph= infoTable.getRow(row).getCell(col).addParagraph();
            XWPFRun cellParagraphRun = celXWPFParagraph.createRun();
            cellParagraphRun.setText(dataList.get(i));
            cellParagraphRun.setColor("000000");
            cellParagraphRun.setFontSize(14);
            col++;
        }
        saveDocument(document,path);
    }
    /**
     * 合并单元格方法
     *
     * @param list     表格头部数据 list中相连下标位置内容如果相同自动合并 上下位置内容相同自动合并
     * @param dataList 表格内容数据   按顺序填入集合中即可
     * @param colWidths 表格内容数据   按顺序填入集合中即可
     * @param jhlx 表格内容数据   按顺序填入集合中即可
     * @return
     */
    public void makeDataJh(List<List<String>> list, List<String> dataList,int[] colWidths ,String jhlx) throws Exception {
        int length = list.get(0).size();
        List<List<Map<String, String>>> aa = new ArrayList<>();

        for (int i = 0; i < list.size(); i++) {
            List<String> strings = list.get(i);
            int colNum = 1;
            List<Map<String, String>> bb = new ArrayList<>();
            for (int j = 0; j < strings.size(); j++) {
                if (j + 1 < strings.size()) {
                    if (strings.get(j).equals(strings.get(j + 1))&&false) {//不过滤行
                        colNum++;
                    } else {
                        Map<String, String> map = new HashMap<>();
                        map.put("value", strings.get(j));
                        map.put("colspan", colNum + "");

                        bb.add(map);

                        for (int a = 1; a < colNum; a++) {
                            bb.add(null);
                        }
                        colNum = 1;
                    }
                } else {
                    System.out.println("de"+colNum);
                    Map<String, String> map = new HashMap<>();
                    map.put("value", strings.get(j));
                    map.put("colspan", colNum + "");
                    bb.add(map);
                    for (int a = 1; a < colNum; a++) {
                        bb.add(null);
                    }
                    colNum = 1;
                }
            }
            aa.add(bb);
        }
        System.out.println(aa.toString());
        for (int i = 0; i < length; i++) {

            int rowSpan = 1;
            int begrow=0;

            for (int j = 0; j < aa.size(); j++) {

                if (aa.get(j).get(i) == null) {
                    continue;
                }

                if (j + 1 < aa.size()) {

                    if (checkValue(list,j,(j+(1)),i)&&aa.get(j + 1).get(i) != null && aa.get(j).get(i).get("value").equals(aa.get(j + 1).get(i).get("value"))
                            && aa.get(j).get(i).get("colspan").equals(aa.get(j + 1).get(i).get("colspan"))
                    ) {

                        rowSpan++;
                    } else {
                        //checkValue(list,0,0,i)&&
                        begrow=j;
                        aa.get(j - rowSpan + 1).get(i).put("rowSpan", rowSpan + "");

                        for (int a = 1; a < rowSpan; a++) {
                            aa.get(j - rowSpan + 1 + a).set(i, null);
                        }
                        rowSpan = 1;


                    }
                } else {
                    begrow=j;
                    aa.get(j - rowSpan + 1).get(i).put("rowSpan", rowSpan + "");

                    for (int a = 1; a < rowSpan; a++) {
                        aa.get(j - rowSpan + 1 + a).set(i, null);
                    }
                    rowSpan = 1;
                }
            }
        }


        List<List<Map<String, Boolean>>> mergeList = new ArrayList<>();
        for (int i = 0; i < aa.size(); i++) {
            List<Map<String, Boolean>> list1 = new ArrayList<>();
            for (int j = 0; j < aa.get(0).size(); j++) {

                Map<String, String> map1 = aa.get(i).get(j);

                if (map1 != null && map1.size() >= 3) {
                    int rowSpan = Integer.parseInt(map1.get("rowSpan"));
                    int colspan = Integer.parseInt(map1.get("colspan"));

                    if (colspan > 1) {

                        aa.get(i).get(j).put("isColStart", "true");

                        for (int a = 1; a < colspan; a++) {
                            Map<String, String> map = new HashMap<>();
                            map.put("isColContinue", "true");
                            aa.get(i).set(j + a, map);
                        }
                    }
                    if (rowSpan > 1) {

                        aa.get(i).get(j).put("isRowStart", "true");

                        if (colspan > 1) {
                            for (int a = 1; a < rowSpan; a++) {
                                Map<String, String> map = new HashMap<>();
                                map.put("isRowContinue", "true");
                                aa.get(i + a).set(j, map);

                                for (int b = 1; b < colspan; b++) {
                                    Map<String, String> map2 = new HashMap<>();
                                    map2.put("isColContinue", "true");
                                    map2.put("isRowContinue", "true");
                                    aa.get(i + a).set(j + b, map2);
                                }
                            }
                        } else {
                            for (int a = 1; a < rowSpan; a++) {
                                Map<String, String> map = new HashMap<>();
                                map.put("isRowContinue", "true");
                                aa.get(i + a).set(j, map);
                            }
                        }
                    }

                }
            }
            mergeList.add(list1);
        }

        //基本信息表格
        XWPFTable infoTable = document.createTable(dataList == null ? list.size() : list.size() + dataList.size() / list.get(0).size(), list.get(0).size());

        //设置指定宽度
        //CTTbl ttbl = infoTable.getCTTbl();
        //CTTblGrid tblGrid = ttbl.addNewTblGrid();
        //for (int i : colWidths) {
        //CTTblGridCol gridCol = tblGrid.addNewGridCol();
        //gridCol.setW(new BigInteger(i+"")); 暂时i不指定
        //}
        infoTable.setTableAlignment(TableRowAlign.CENTER);//居中
        //自适应
        CTTblWidth comTableWidth = infoTable.getCTTbl().addNewTblPr().addNewTblW();
        comTableWidth.setType(STTblWidth.DXA);
        comTableWidth.setW(BigInteger.valueOf(20000));

        //
        //CTTblWidth comTableWidth = infoTable.getCTTbl().addNewTblPr().addNewTblW();
        //comTableWidth.setType(STTblWidth.DXA);
        //comTableWidth.setW(BigInteger.valueOf(9072));



        for (int i = 0; i < list.size(); i++) {
            //表格第一行
            XWPFTableRow infoTableRowOne = infoTable.getRow(i);
            for (int j = 0; j < list.get(0).size(); j++) {

                Map<String, String> map = aa.get(i).get(j);

                if (map.get("isColStart") != null) {
                    //infoTableRowOne.getCell(j).getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.RESTART);//这是起点
                }
                if (map.get("isRowStart") != null) {
                    infoTableRowOne.getCell(j).getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.RESTART);//这是起点
                }
                if (map.get("isColContinue") != null) {
                    //infoTableRowOne.getCell(j).getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.CONTINUE);//这是起点
                }
                if (map.get("isRowContinue") != null) {
                    infoTableRowOne.getCell(j).getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.CONTINUE);//这是起点
                }
                if (map.get("value") != null) {
                    //infoTableRowOne.getCell(j).setText(map.get("value"));
                    XWPFParagraph XWPFParagraph1=(XWPFParagraph)infoTableRowOne.getCell(j).getParagraphs().get(0);
                    //XWPFParagraph celXWPFParagraph= infoTableRowOne.getCell(j).addParagraph();
                    XWPFRun cellParagraphRun = XWPFParagraph1.createRun();
                    cellParagraphRun.setText(map.get("value"));
                    cellParagraphRun.setColor("000000");
                    cellParagraphRun.setFontSize(14);
                    if(i==0||i==1){
                        cellParagraphRun.setFontSize(13);
                        XWPFParagraph1.setAlignment(ParagraphAlignment.CENTER);  //设置水平居中
                        infoTableRowOne.getCell(j).setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);  //设置垂直居中//垂直居中
                        //infoTableRowOne.getCell(j).setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
                        //celXWPFParagraph.setVerticalAlignment(TextAlignment.CENTER);
                        //水平居中
                        //celXWPFParagraph.setAlignment(ParagraphAlignment.CENTER);
                    }
                }
                //XWPFParagraph XWPFParagraph1=(XWPFParagraph)infoTableRowOne.getCell(j).getParagraphs().get(0);


                //infoTableRowOne.getCell(j).setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);  //设置垂直居中
            }
        }
        int row = list.size() - 1;
        int col = 0;
        for (int i = 0; i < dataList.size(); i++) {
            if (i % list.get(0).size() == 0) {
                row++;
                col = 0;
            }
            //infoTable.getRow(row).getCell(col).setText(dataList.get(i));
            //infoTable.getRow(row).getCell(col).set
            System.out.println("新宽度");
            XWPFParagraph celXWPFParagraph= infoTable.getRow(row).getCell(col).addParagraph();
            XWPFRun cellParagraphRun = celXWPFParagraph.createRun();
            cellParagraphRun.setText(dataList.get(i));
            cellParagraphRun.setColor("000000");
            cellParagraphRun.setFontSize(14);
            col++;
        }
        //saveDocument(document,path);
        //合并单元格  length  infoTable
        /*
            先合并倒数 第一和第二
         */
        log.writeLog("开始合并---begin");
        infoTable.getRow(0).getCell(length-1).getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.RESTART);
        infoTable.getRow(1).getCell(length-1).getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.CONTINUE);
        infoTable.getRow(0).getCell(length-2).getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.RESTART);
        infoTable.getRow(1).getCell(length-2).getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.CONTINUE);
        //合并行
        if("0".equals(jhlx)){//季度
            log.writeLog(length-(1+2+3));
            log.writeLog(length-(1+2));
            CTHMerge CTVMerge=CTHMerge.Factory.newInstance();
            CTVMerge.setVal(STMerge.RESTART);
            CTHMerge CTVMerge1=CTHMerge.Factory.newInstance();
            CTVMerge.setVal(STMerge.CONTINUE);
            infoTable.getRow(0).getCell(length-(1+2+3)).getCTTc().getTcPr().setHMerge(CTVMerge);
            double width1 = 20000*((double)(((length-(1+2))-(length-(1+2+3)))+1)/length);
            int width=(int)width1;
            log.writeLog("width"+width);
            log.writeLog("width1"+infoTable.getCTTbl().getTblPr().getTblW().getW().intValue());
            //infoTable.getRow(0).getCell(length-(1+2+3)).getCTTc().getTcPr().addNewTcW().setW(BigInteger.valueOf(width));

            infoTable.getRow(0).getCell(length-(1+2)).getCTTc().getTcPr().setHMerge(CTVMerge1);
            //infoTable.getRow(0).getCell(length-(1+2+3)).getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.RESTART);
            //infoTable.getRow(0).getCell(length-(1+2)).getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.CONTINUE);
        }else{
            infoTable.getRow(0).getCell(length-(1+2+1)).getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.RESTART);
            infoTable.getRow(0).getCell(length-(1+2)).getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.CONTINUE);
        }


    }
    /**
     * 合并单元格方法
     *
     * @param list     表格头部数据 list中相连下标位置内容如果相同自动合并 上下位置内容相同自动合并
     * @param dataList 表格内容数据   按顺序填入集合中即可
     * @return
     */
    public void makeData(List<List<String>> list, List<String> dataList,int[] colWidths ) throws Exception {
        int length = list.get(0).size();
        List<List<Map<String, String>>> aa = new ArrayList<>();

        for (int i = 0; i < list.size(); i++) {
            List<String> strings = list.get(i);
            int colNum = 1;
            List<Map<String, String>> bb = new ArrayList<>();
            for (int j = 0; j < strings.size(); j++) {
                if (j + 1 < strings.size()) {
                    if (strings.get(j).equals(strings.get(j + 1))&&false) {//不过滤行
                        colNum++;
                    } else {
                        Map<String, String> map = new HashMap<>();
                        map.put("value", strings.get(j));
                        map.put("colspan", colNum + "");

                        bb.add(map);

                        for (int a = 1; a < colNum; a++) {
                            bb.add(null);
                        }
                        colNum = 1;
                    }
                } else {
                    System.out.println("de"+colNum);
                    Map<String, String> map = new HashMap<>();
                    map.put("value", strings.get(j));
                    map.put("colspan", colNum + "");
                    bb.add(map);
                    for (int a = 1; a < colNum; a++) {
                        bb.add(null);
                    }
                    colNum = 1;
                }
            }
            aa.add(bb);
        }
        System.out.println(aa.toString());
        for (int i = 0; i < length; i++) {

            int rowSpan = 1;
            int begrow=0;

            for (int j = 0; j < aa.size(); j++) {

                if (aa.get(j).get(i) == null) {
                    continue;
                }

                if (j + 1 < aa.size()) {

                    if (checkValue(list,j,(j+(1)),i)&&aa.get(j + 1).get(i) != null && aa.get(j).get(i).get("value").equals(aa.get(j + 1).get(i).get("value"))
                            && aa.get(j).get(i).get("colspan").equals(aa.get(j + 1).get(i).get("colspan"))
                    ) {

                        rowSpan++;
                    } else {
                        //checkValue(list,0,0,i)&&
                        begrow=j;
                        aa.get(j - rowSpan + 1).get(i).put("rowSpan", rowSpan + "");

                        for (int a = 1; a < rowSpan; a++) {
                            aa.get(j - rowSpan + 1 + a).set(i, null);
                        }
                        rowSpan = 1;


                    }
                } else {
                    begrow=j;
                    aa.get(j - rowSpan + 1).get(i).put("rowSpan", rowSpan + "");

                    for (int a = 1; a < rowSpan; a++) {
                        aa.get(j - rowSpan + 1 + a).set(i, null);
                    }
                    rowSpan = 1;
                }
            }
        }


        List<List<Map<String, Boolean>>> mergeList = new ArrayList<>();
        for (int i = 0; i < aa.size(); i++) {
            List<Map<String, Boolean>> list1 = new ArrayList<>();
            for (int j = 0; j < aa.get(0).size(); j++) {

                Map<String, String> map1 = aa.get(i).get(j);

                if (map1 != null && map1.size() >= 3) {
                    int rowSpan = Integer.parseInt(map1.get("rowSpan"));
                    int colspan = Integer.parseInt(map1.get("colspan"));

                    if (colspan > 1) {

                        aa.get(i).get(j).put("isColStart", "true");

                        for (int a = 1; a < colspan; a++) {
                            Map<String, String> map = new HashMap<>();
                            map.put("isColContinue", "true");
                            aa.get(i).set(j + a, map);
                        }
                    }
                    if (rowSpan > 1) {

                        aa.get(i).get(j).put("isRowStart", "true");

                        if (colspan > 1) {
                            for (int a = 1; a < rowSpan; a++) {
                                Map<String, String> map = new HashMap<>();
                                map.put("isRowContinue", "true");
                                aa.get(i + a).set(j, map);

                                for (int b = 1; b < colspan; b++) {
                                    Map<String, String> map2 = new HashMap<>();
                                    map2.put("isColContinue", "true");
                                    map2.put("isRowContinue", "true");
                                    aa.get(i + a).set(j + b, map2);
                                }
                            }
                        } else {
                            for (int a = 1; a < rowSpan; a++) {
                                Map<String, String> map = new HashMap<>();
                                map.put("isRowContinue", "true");
                                aa.get(i + a).set(j, map);
                            }
                        }
                    }

                }
            }
            mergeList.add(list1);
        }

        //基本信息表格
        XWPFTable infoTable = document.createTable(dataList == null ? list.size() : list.size() + dataList.size() / list.get(0).size(), list.get(0).size());

        //设置指定宽度
        //CTTbl ttbl = infoTable.getCTTbl();
        //CTTblGrid tblGrid = ttbl.addNewTblGrid();
        //for (int i : colWidths) {
            //CTTblGridCol gridCol = tblGrid.addNewGridCol();
            //gridCol.setW(new BigInteger(i+"")); 暂时i不指定
        //}
        infoTable.setTableAlignment(TableRowAlign.CENTER);//居中
        //自适应
        CTTblWidth comTableWidth = infoTable.getCTTbl().addNewTblPr().addNewTblW();
        comTableWidth.setType(STTblWidth.DXA);
        comTableWidth.setW(BigInteger.valueOf(20000));

        //
        //CTTblWidth comTableWidth = infoTable.getCTTbl().addNewTblPr().addNewTblW();
        //comTableWidth.setType(STTblWidth.DXA);
        //comTableWidth.setW(BigInteger.valueOf(9072));



        for (int i = 0; i < list.size(); i++) {
            //表格第一行
            XWPFTableRow infoTableRowOne = infoTable.getRow(i);
            for (int j = 0; j < list.get(0).size(); j++) {

                Map<String, String> map = aa.get(i).get(j);

                if (map.get("isColStart") != null) {
                    //infoTableRowOne.getCell(j).getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.RESTART);//这是起点
                }
                if (map.get("isRowStart") != null) {
                    infoTableRowOne.getCell(j).getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.RESTART);//这是起点
                }
                if (map.get("isColContinue") != null) {
                    //infoTableRowOne.getCell(j).getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.CONTINUE);//这是起点
                }
                if (map.get("isRowContinue") != null) {
                    infoTableRowOne.getCell(j).getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.CONTINUE);//这是起点
                }
                if (map.get("value") != null) {
                    //infoTableRowOne.getCell(j).setText(map.get("value"));
                    XWPFParagraph XWPFParagraph1=(XWPFParagraph)infoTableRowOne.getCell(j).getParagraphs().get(0);
                    //XWPFParagraph celXWPFParagraph= infoTableRowOne.getCell(j).addParagraph();
                    XWPFRun cellParagraphRun = XWPFParagraph1.createRun();
                    cellParagraphRun.setText(map.get("value"));
                    cellParagraphRun.setColor("000000");
                    cellParagraphRun.setFontSize(14);
                    if(i==0){
                        cellParagraphRun.setFontSize(13);
                        XWPFParagraph1.setAlignment(ParagraphAlignment.CENTER);  //设置水平居中
                        infoTableRowOne.getCell(j).setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);  //设置垂直居中//垂直居中
                        //infoTableRowOne.getCell(j).setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
                        //celXWPFParagraph.setVerticalAlignment(TextAlignment.CENTER);
                        //水平居中
                        //celXWPFParagraph.setAlignment(ParagraphAlignment.CENTER);
                    }
                }
                //XWPFParagraph XWPFParagraph1=(XWPFParagraph)infoTableRowOne.getCell(j).getParagraphs().get(0);


                //infoTableRowOne.getCell(j).setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);  //设置垂直居中
            }
        }
        int row = list.size() - 1;
        int col = 0;
        for (int i = 0; i < dataList.size(); i++) {
            if (i % list.get(0).size() == 0) {
                row++;
                col = 0;
            }
            //infoTable.getRow(row).getCell(col).setText(dataList.get(i));
            //infoTable.getRow(row).getCell(col).set
            System.out.println("新宽度");
            XWPFParagraph celXWPFParagraph= infoTable.getRow(row).getCell(col).addParagraph();
            XWPFRun cellParagraphRun = celXWPFParagraph.createRun();
            cellParagraphRun.setText(dataList.get(i));
            cellParagraphRun.setColor("000000");
            cellParagraphRun.setFontSize(14);
            col++;
        }
        //saveDocument(document,path);

    }
    /**
     * 合并单元格方法
     *
     * @param list     表格头部数据 list中相连下标位置内容如果相同自动合并 上下位置内容相同自动合并
     * @param dataList 表格内容数据   按顺序填入集合中即可
     * @return
     */
    public void makeData1(List<List<String>> list, List<String> dataList,int[] colWidths,String path) throws Exception {
        int length = list.get(0).size();
        List<List<Map<String, String>>> aa = new ArrayList<>();

        for (int i = 0; i < list.size(); i++) {
            List<String> strings = list.get(i);
            int colNum = 1;
            List<Map<String, String>> bb = new ArrayList<>();
            for (int j = 0; j < strings.size(); j++) {
                if (j + 1 < strings.size()) {
                    if (strings.get(j).equals(strings.get(j + 1))) {
                        colNum++;
                    } else {
                        Map<String, String> map = new HashMap<>();
                        map.put("value", strings.get(j));
                        map.put("colspan", colNum + "");

                        bb.add(map);

                        for (int a = 1; a < colNum; a++) {
                            bb.add(null);
                        }
                        colNum = 1;
                    }
                } else {
                    Map<String, String> map = new HashMap<>();
                    map.put("value", strings.get(j));
                    map.put("colspan", colNum + "");
                    bb.add(map);
                    for (int a = 1; a < colNum; a++) {
                        bb.add(null);
                    }
                    colNum = 1;
                }
            }
            aa.add(bb);
        }

        for (int i = 0; i < length; i++) {

            int rowSpan = 1;

            for (int j = 0; j < aa.size(); j++) {

                if (aa.get(j).get(i) == null) {
                    continue;
                }

                if (j + 1 < aa.size()) {

                    if (aa.get(j + 1).get(i) != null && aa.get(j).get(i).get("value").equals(aa.get(j + 1).get(i).get("value"))
                            && aa.get(j).get(i).get("colspan").equals(aa.get(j + 1).get(i).get("colspan"))
                    ) {
                        rowSpan++;
                    } else {
                        aa.get(j - rowSpan + 1).get(i).put("rowSpan", rowSpan + "");

                        for (int a = 1; a < rowSpan; a++) {
                            aa.get(j - rowSpan + 1 + a).set(i, null);
                        }
                        rowSpan = 1;
                    }
                } else {
                    aa.get(j - rowSpan + 1).get(i).put("rowSpan", rowSpan + "");

                    for (int a = 1; a < rowSpan; a++) {
                        aa.get(j - rowSpan + 1 + a).set(i, null);
                    }
                    rowSpan = 1;
                }
            }
        }


        List<List<Map<String, Boolean>>> mergeList = new ArrayList<>();
        for (int i = 0; i < aa.size(); i++) {
            List<Map<String, Boolean>> list1 = new ArrayList<>();
            for (int j = 0; j < aa.get(0).size(); j++) {

                Map<String, String> map1 = aa.get(i).get(j);

                if (map1 != null && map1.size() >= 3) {
                    int rowSpan = Integer.parseInt(map1.get("rowSpan"));
                    int colspan = Integer.parseInt(map1.get("colspan"));

                    if (colspan > 1) {

                        aa.get(i).get(j).put("isColStart", "true");

                        for (int a = 1; a < colspan; a++) {
                            Map<String, String> map = new HashMap<>();
                            map.put("isColContinue", "true");
                            aa.get(i).set(j + a, map);
                        }
                    }
                    if (rowSpan > 1) {

                        aa.get(i).get(j).put("isRowStart", "true");

                        if (colspan > 1) {
                            for (int a = 1; a < rowSpan; a++) {
                                Map<String, String> map = new HashMap<>();
                                map.put("isRowContinue", "true");
                                aa.get(i + a).set(j, map);

                                for (int b = 1; b < colspan; b++) {
                                    Map<String, String> map2 = new HashMap<>();
                                    map2.put("isColContinue", "true");
                                    map2.put("isRowContinue", "true");
                                    aa.get(i + a).set(j + b, map2);
                                }
                            }
                        } else {
                            for (int a = 1; a < rowSpan; a++) {
                                Map<String, String> map = new HashMap<>();
                                map.put("isRowContinue", "true");
                                aa.get(i + a).set(j, map);
                            }
                        }
                    }

                }
            }
            mergeList.add(list1);
        }

        //基本信息表格
        //XWPFTable infoTable = document.createTable(dataList == null ? list.size() : list.size() + dataList.size() / list.get(0).size(), list.get(0).size());
        XWPFTable infoTable = document.createTable(dataList == null ? list.size() : list.size() + dataList.size() , list.get(0).size());
        //设置指定宽度
        CTTbl ttbl = infoTable.getCTTbl();
        CTTblGrid tblGrid = ttbl.addNewTblGrid();
        for (int i : colWidths) {
            CTTblGridCol gridCol = tblGrid.addNewGridCol();
            gridCol.setW(new BigInteger(i+""));
        }


        for (int i = 0; i < dataList.size(); i++) {
            //表格第一行
            XWPFTableRow infoTableRowOne = infoTable.getRow(i);
            for (int j = 0; j < dataList.size(); j++) {

                Map<String, String> map = aa.get(i).get(j);

                if (map.get("isColStart") != null) {
                    //infoTableRowOne.getCell(j).getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.RESTART);//这是起点
                }
                if (map.get("isRowStart") != null) {
                    infoTableRowOne.getCell(j).getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.RESTART);//这是起点
                }
                if (map.get("isColContinue") != null) {
                    //infoTableRowOne.getCell(j).getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.CONTINUE);//这是起点
                }
                if (map.get("isRowContinue") != null) {
                    infoTableRowOne.getCell(j).getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.CONTINUE);//这是起点
                }
                if (map.get("value") != null) {
                    infoTableRowOne.getCell(j).setText(map.get("value"));
                }
                XWPFParagraph XWPFParagraph1=(XWPFParagraph)infoTableRowOne.getCell(j).getParagraphs().get(0);
                XWPFParagraph1.setAlignment(ParagraphAlignment.CENTER);  //设置水平居中

                infoTableRowOne.getCell(j).setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);  //设置垂直居中
            }
        }
        int row = list.size() - 1;
        int col = 0;
        //for (int i = 0; i < dataList.size(); i++) {
        for (int i = 0; i < list.size(); i++) {
            if (i % list.get(0).size() == 0) {
                row++;
                col = 0;
            }
            infoTable.getRow(row).getCell(col).setText(dataList.get(i));
            col++;
        }
        saveDocument(document,path);
    }

    //
    public void saveDocument(XWPFDocument document, String savePath) throws IOException {
        OutputStream os = new FileOutputStream(savePath);
        document.write(os);
        os.close();
    }
    /*
        判断 两列之前的数据 是否一致  fromrow 从1 开始
     */
    public boolean checkValue(List<List<String>> listdata,int fromrow,int torow,int cell){
        boolean flag=false;
        if(listdata.size()>0&&fromrow>=0&&torow>=0&&cell>=0&&listdata.size()>fromrow&&listdata.get(0).size()>cell){
            if(cell==0){
                return true;
            }else{
                String begstr= listdata.get(fromrow).get(cell-1);
                String endstr=  listdata.get(torow).get(cell-1);
                if(begstr.equals(endstr)){
                    flag=true;
                    //递归
                    flag=checkValue(listdata,fromrow,torow,(cell-1));
                }else{
                    flag=false;
                }
            }
        }
        return flag;
    }
}